home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / ofiles2 < prev    next >
Encoding:
Text File  |  1991-12-19  |  47.2 KB  |  2,078 lines

  1. Newsgroups: comp.sources.unix
  2. From: ehrlich@margaux.inria.fr (Robert Ehrlich)
  3. Subject: v25i072: ofiles2 - a portable version of ofiles (show list of open files)
  4. Sender: sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: ehrlich@margaux.inria.fr (Robert Ehrlich)
  8. Posting-Number: Volume 25, Issue 72
  9. Archive-Name: ofiles2
  10.  
  11. [ I grabbed the Makefile and man page from the last version of ofiles that
  12.   was posted here; the man page needed some editing, which I did, so if there
  13.   are bugs in the man page it's my fault.                --vix ]
  14.  
  15. This is a heavily reworked version of ofiles. Ofiles shows identifys the
  16. opener of a file.  It was modified to be more portable and is known to work
  17. on several architectures :
  18.  
  19.         - Suns 3 and 4 under SunOs from 3.0 to 4.1.1
  20.         - Sony 1xxx 68k under newsOS 3.0 to 4.0
  21.         - Sony 3xxx RISC under newsOS 3.5 to 4.0
  22.         - Decstation 3100 under Ultrix 2.2 to 4.1
  23.         - Pyramid OSX 5.0 (with vtophys.c from OSX sources)
  24.         - Vax BSD4.3 and Ultrix
  25.         - Sequent DYNIX 3.0
  26.  
  27. The author of the rework is Robert Ehrlich (ehrlich@margaux.inria.fr).
  28.  
  29. #! /bin/sh
  30. # This is a shell archive.  Remove anything before this line, then unpack
  31. # it by saving it into a file and typing "sh file".  To overwrite existing
  32. # files, type "sh file -c".  You can also feed this as standard input via
  33. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  34. # will see the following message at the end:
  35. #        "End of archive 1 (of 1)."
  36. # Contents:  MANIFEST Makefile README ofiles.8l ofiles.c
  37. # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 20 14:31:10 1991
  38. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  39. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  40.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  41. else
  42. echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
  43. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  44. X   File Name        Archive #    Description
  45. X-----------------------------------------------------------
  46. X MANIFEST                   1    
  47. X Makefile                   1    
  48. X README                     1    
  49. X ofiles.8l                  1    
  50. X ofiles.c                   1    
  51. END_OF_FILE
  52. if test 251 -ne `wc -c <'MANIFEST'`; then
  53.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  54. fi
  55. # end of 'MANIFEST'
  56. fi
  57. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  58.   echo shar: Will not clobber existing file \"'Makefile'\"
  59. else
  60. echo shar: Extracting \"'Makefile'\" \(738 characters\)
  61. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  62. X#
  63. X#    Makefile for ofiles
  64. X#
  65. X
  66. PROG=    ofiles
  67. BIN=    ${DESTDIR}/usr/local/etc
  68. X
  69. I=/usr/include
  70. S=/usr/include/sys
  71. L=/usr/include/local
  72. X
  73. INCLUDE=
  74. DEBUG=    -O
  75. CDEFS=  
  76. CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
  77. X
  78. HDR=    
  79. ONEC=    ofiles.c
  80. OTHER=    
  81. SOURCE=    Makefile ${HDR} ${ONEC} ${OTHER}
  82. X
  83. all: ${PROG}
  84. X
  85. X# SunOS 4.0 needs -lkvm in the following rule
  86. X
  87. X${PROG}:
  88. X    ${CC} -o $@ ${CFLAGS} ${ONEC} 
  89. X
  90. clean: FRC
  91. X    rm -f Makefile.bak ${PROG} *.o a.out core errs tags
  92. X
  93. install: all FRC
  94. X    install -cs -m 2755 -g kmem ${PROG} ${BIN}
  95. X
  96. lint: ${HDR} ${ONEC} FRC
  97. X    lint ${CDEFS} ${INCLUDE} ${ONEC}
  98. X
  99. print: source FRC
  100. X    lpr -J'${PROG} source' ${SOURCE}
  101. X
  102. source: ${SOURCE}
  103. X
  104. spotless: clean
  105. X    rcsclean ${SOURCE}
  106. X
  107. tags: ${HDR} ${ONEC}
  108. X    ctags -t ${HDR} ${ONEC}
  109. X
  110. X${SOURCE}:
  111. X    co -q $@
  112. X
  113. XFRC:
  114. X
  115. END_OF_FILE
  116. if test 738 -ne `wc -c <'Makefile'`; then
  117.     echo shar: \"'Makefile'\" unpacked with wrong size!
  118. fi
  119. # end of 'Makefile'
  120. fi
  121. if test -f 'README' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'README'\"
  123. else
  124. echo shar: Extracting \"'README'\" \(1088 characters\)
  125. sed "s/^X//" >'README' <<'END_OF_FILE'
  126. This is a heavily reworked version of ofiles. Ofiles shows identifys the
  127. opener of a file.
  128. It was modified to be more portable and is known to work on several
  129. architectures :
  130. X    - Suns 3 and 4 under SunOs from 3.0 to 4.1.1
  131. X    - Sony 1xxx 68k under newsOS 3.0 to 4.0
  132. X    - Sony 3xxx RISC under newsOS 3.5 to 4.0
  133. X    - Decstation 3100 under Ultrix 2.2 to 4.1
  134. X    - Pyramid OSX 5.0 (with vtophys.c from OSX sources)
  135. X    - Vax BSD4.3 and Ultrix
  136. X    - Sequent DYNIX 3.0
  137. This is a heavily reworked version of ofiles. Ofiles shows identifies the
  138. opener of a file.
  139. It has proved to be very portable, and should work on many other
  140. architectures if you mess a little bit with the #defines. The code base is
  141. all there, but it needs configuration.
  142. X
  143. There is no makefile because it is so simple to compile. You just need to
  144. provide the right libraries :
  145. Sun:
  146. X    cc ofiles.c -o ofiles -lkvm
  147. Sony:
  148. X    cc ofiles.c -o ofiles -lmld
  149. It needs two things : a symbol extraction library and a kernel memory access
  150. library. On most systems one or the other is already in the libc.
  151. X
  152. X
  153. Send Bugs and comments to ehrlich@margaux.inria.fr.
  154. END_OF_FILE
  155. if test 1088 -ne `wc -c <'README'`; then
  156.     echo shar: \"'README'\" unpacked with wrong size!
  157. fi
  158. # end of 'README'
  159. fi
  160. if test -f 'ofiles.8l' -a "${1}" != "-c" ; then 
  161.   echo shar: Will not clobber existing file \"'ofiles.8l'\"
  162. else
  163. echo shar: Extracting \"'ofiles.8l'\" \(5890 characters\)
  164. sed "s/^X//" >'ofiles.8l' <<'END_OF_FILE'
  165. X.TH OFILES 8L LOCAL
  166. X.SH NAME
  167. ofiles \- show owner of open file or network connection
  168. X.SH SYNOPSIS
  169. X.B ofiles
  170. X[
  171. X.B \-Dnpimfd
  172. X] [
  173. X.B \-k
  174. X.I nlist
  175. X.I core
  176. X]
  177. X.I names
  178. X.SH DESCRIPTION
  179. X.I Ofiles
  180. displays the owner, process identification (PID), type, command and
  181. the number of the inode associated with an open instance of a file
  182. or a network connection.
  183. X.PP
  184. An open file may be a regular file, a file system or a directory;
  185. it is specified by its path name.
  186. When the path name refers to a file system,
  187. X.I ofiles
  188. will display the owners of all open instances of files in the system.
  189. X.PP
  190. An open network connection is specified by the kernel address of its
  191. Protocol Control Block (PCB), as displayed by
  192. X.IR netstat (8),
  193. when its
  194. X.B \-A
  195. option is specified.
  196. X.SH OPTIONS
  197. X.I Ofiles
  198. displays information about its usage if no options are specified.
  199. X.TP \w'-kXnlistXcore'u+4
  200. X.BI \-D
  201. This option selects verbose, debugging output.
  202. X.TP
  203. X.BI \-k \ nlist\ core
  204. This option may be used only on DYNIX hosts.
  205. It sets optional name list and core file paths.
  206. X.IP
  207. X.I Nlist
  208. is the path to the file from which
  209. X.I ofiles
  210. should obtain the addresses of kernel symbols,
  211. instead of from
  212. X.IR /dynix .
  213. X.IP
  214. X.I Core
  215. is the path to the file from which
  216. X.I ofiles
  217. should obtain the value of kernel symbols,
  218. instead of from
  219. X.IR /dev/mem .
  220. X.IP
  221. This option is useful for debugging system crash dumps.
  222. X.TP
  223. X.B \-n
  224. This option specifies that the
  225. X.I name
  226. arguments identify network connections by their hexadecimal, Protocol
  227. Control Block (PCB) addresses.
  228. PCB addresses can be obtained via the
  229. X.B \-A
  230. option of
  231. X.IR netstat (1).
  232. X.IP
  233. This option makes it possible to determine the local processes that
  234. are using network connections in the LISTEN through ESTABLISHED states.
  235. X.TP
  236. X.B \-p 
  237. This option specifies that
  238. X.I ofiles
  239. should print process identifiers only \- e. g., so that the output may
  240. be piped to
  241. X.IR kill (1).
  242. X.TP
  243. X.B "\-m, \-f, \-d"
  244. These options force the argument to be considered a
  245. mount point, regular file, and device respectively.
  246. X.TP
  247. X.I names
  248. These are path names of files, directories and file systems;
  249. or, if the
  250. X.B \-n
  251. option has been specified, network connections, identified by their
  252. hexadecimal Protocol Control Block (PCB) addresses.
  253. X.SH OUTPUT
  254. X.I Ofiles
  255. displays for each
  256. X.IR name :
  257. X.TP \w'name/linkages'u+4
  258. X.I name/linkages
  259. for file paths, an interpretation of the type of name \- file, directory
  260. or file system;
  261. for network connections, the kernel address linkages, starting with the file
  262. structure and proceeding through the socket structure and the Internet
  263. Protocol Control Block (INPCB) structure to the PCB
  264. X.TP
  265. X.B USER
  266. the login name of the user of the process that has
  267. X.I name
  268. open
  269. X.TP
  270. X.B PID
  271. the identifier of the process that has
  272. X.I name
  273. open
  274. X.TP
  275. X.B TYPE
  276. a file type explanation:
  277. X.RS
  278. X.TP \w'file'u+4
  279. X.B cwd 
  280. if
  281. X.I name
  282. is the current working directory of the process
  283. X.TP
  284. X.B file
  285. if
  286. X.I name
  287. is being used as a regular file by the process, optionally followed by:
  288. X.RS
  289. X.TP
  290. X.B /s
  291. if the process has a shared lock on the file
  292. X.TP
  293. X.B /x
  294. if the process has an exclusive lock on the file
  295. X.RE
  296. X.TP
  297. X.B rdir
  298. if 
  299. X.I name
  300. is the root directory of the process
  301. X.TP
  302. X.B sock
  303. if
  304. X.I name
  305. is a socket
  306. X.RE
  307. X.TP
  308. X.B FD
  309. the file descriptor number, local to the process
  310. X.TP
  311. X.B CMD
  312. the user command that opened
  313. X.I name
  314. X.TP
  315. X.B INODE
  316. the inode number of the file
  317. X.SH EXAMPLES
  318. This example shows the use of
  319. X.I ofiles
  320. to discover the owner of the open, regular file,
  321. X.IR /usr/spool/lpd/lock .
  322. X.PP
  323. X.RS
  324. X.nf
  325. X% ofiles /usr/spool/lpd/lock
  326. X.br
  327. X/usr/spool/lpd/lock    
  328. X.br
  329. USER    PID    TYPE      FD    CMD    INODE
  330. X.br
  331. root    110    file/x     3    lpd    26683
  332. X.fi
  333. X.RE
  334. X.PP
  335. This example shows the use of
  336. X.IR netstat (1),
  337. X.IR grep (1)
  338. and
  339. X.I ofiles
  340. to identify the local endpoint of the ``smtp'' network connection.
  341. The first column of output from
  342. X.I netstat
  343. is the PCB address; it is used as the
  344. X.I name
  345. argument to
  346. X.IR ofiles ,
  347. along with the
  348. X.B \-n
  349. option.
  350. X.PP
  351. X.RS
  352. X.nf
  353. X% netstat -aA | grep smtp
  354. X.br
  355. X80f6770c    tcp    0    0    *.smtp    *.*    LISTEN
  356. X.br
  357. X% ofiles -n 80f6770c
  358. X.br
  359. file 80102b64 of socket 80f6758c of INPCB 80f6780c of PCB 80f6770c    
  360. X.br
  361. USER    PID    TYPE    FD    CMD
  362. X.br
  363. root    105    sock     5    sendmail 
  364. X.fi
  365. X.RE
  366. X.SH "THEORY OF OPERATION"
  367. Stat each file or file system argument and scan the process table, looking
  368. for a match in the associated user structure's file lists.  Follow each PCB
  369. arg to the Internet Protocol Control Block (INPCB), thence to the socket;
  370. then scan the file table to find the file structure address associated with
  371. the socket; finally, scan the process table, looking for a nacth in the
  372. associated user structure's file lists.  Now handles remote NFS files.
  373. X.SH DIAGNOSTICS
  374. XErrors are identified with messages on the standard error file.
  375. X.PP
  376. X.I Ofiles
  377. returns a one (1) if any error was detected, including the failure to
  378. locate any
  379. X.IR names .
  380. It returns a zero (0) if no errors were detected and if it was able to
  381. display owner information about all the specified
  382. X.IR names .
  383. X.SH BUGS
  384. X.I Ofiles
  385. can't identify SunOS 4.0 stream files, so it doesn't follow their file
  386. structure pointers correctly when reading their inodes.
  387. That results in the display of erroneous inode numbers for stream files.
  388. X.PP
  389. The
  390. X.B \-n
  391. option limits its search to network connections in the LISTEN through
  392. XESTABLISHED states.
  393. X.PP
  394. Since
  395. X.I ofiles
  396. reads kernel memory in its search for open files and network connections,
  397. rapid changes in kernel memory may produce unsatisfactory results.
  398. X.SH AUTHORS
  399. C. Spencer is the original author.
  400. Michael Ditto, Tom Dunigan, Alexander Dupuy, Gary Nebbett and Richard Tobin
  401. contributed.
  402. X.PP
  403. Michael Spitzer, Ray Moody, and Vik Lall of the Purdue University Computing
  404. Center converted the program to a variety of UNIX environments.
  405. X.PP
  406. Vic Abell of the Purdue University Computing Center added the
  407. X.B \-n
  408. option.
  409. X.PP
  410. The author of this reworked version is Robert Ehrlich
  411. X<ehrlich@margaux.inria.fr>.
  412. X.SH SEE ALSO
  413. inode(5),
  414. mount(1),
  415. kill(1),
  416. tcp(4).
  417. END_OF_FILE
  418. if test 5890 -ne `wc -c <'ofiles.8l'`; then
  419.     echo shar: \"'ofiles.8l'\" unpacked with wrong size!
  420. fi
  421. # end of 'ofiles.8l'
  422. fi
  423. if test -f 'ofiles.c' -a "${1}" != "-c" ; then 
  424.   echo shar: Will not clobber existing file \"'ofiles.c'\"
  425. else
  426. echo shar: Extracting \"'ofiles.c'\" \(34835 characters\)
  427. sed "s/^X//" >'ofiles.c' <<'END_OF_FILE'
  428. X/*    ofiles.c
  429. X *
  430. X *    ofiles [-D ] [-k nlist core] [-n] [-p] [-f|d|m] args
  431. X *
  432. X *    Show owner of open file or network connection.
  433. X *
  434. X *    Reports owner, process ID, access type, command and inode number.
  435. X *
  436. X *    -D        select verbose debugging output
  437. X *
  438. X *    -k nlist core    specifies alternative name list and core files
  439. X *            (DYNIX only)
  440. X *
  441. X *    -n        interpret names as network connection, hexadecimal
  442. X *            Protocol Control Block (PCB) addresses
  443. X *
  444. X *    -p          gives brief (pids only) report
  445. X *
  446. X *    -i        print inode number (ommitted by default)
  447. X *
  448. X *    -m        force argument to be considered as a mount point
  449. X *
  450. X *    -f        force argument to be considered as a regular file
  451. X *
  452. X *    -d        force argument to be considered as a device
  453. X *
  454. X *    names        file names, file system names or network connection
  455. X *            PCB addresses
  456. X *
  457. X *    Stat each file or file system argument and scan the process table,
  458. X *    looking for a match in the associated user structure's file lists.
  459. X *
  460. X *    Follow each PCB arg to the Internet Protocol Control Block (INPCB),
  461. X *    thence to the socket; then scan the file table to find the file
  462. X *    structure address associated with the socket; finally, scan the
  463. X *    process table, looking for a nacth in the associated user structure's
  464. X *    file lists.
  465. X *
  466. X *    Now handles remote NFS files.
  467. X */
  468. X
  469. X/*
  470. X *    Authors:
  471. X *
  472. X *    The orignal author is:
  473. X *
  474. X *        C. Spencer
  475. X *
  476. X *    Contributors include:
  477. X *
  478. X *        Michael Ditto
  479. X *        Tom Dunigan
  480. X *        Alexander Dupuy
  481. X *        Greg Nebbett
  482. X *        Richard Tobin
  483. X *
  484. X *    From the Purdue University Computing Center:
  485. X *
  486. X *        Mike Spitzer         converted to 4.3BSD, DYNIX 3.0.1[24]
  487. X *        Ray Moody        SunOS 4.0 and ULTRIX 2.2
  488. X *        Vik Lall
  489. X *
  490. X *        Vic Abell        added socket option and removed lint
  491. X *    
  492. X *    From INRIA Rocquencourt    (France)
  493. X *        Robert Ehrlich        completely revisited in order to:
  494. X *                - make it work on DECSTATIONs 3100, Pyramid
  495. X *                    OSX, Sony NewsOS 3.5 4.0 risc 68k
  496. X *                - make it work on pre 4.0 SunOS (yes,
  497. X *                    my workstation runs 3.5 !)
  498. X *                - find executable text files, mapped files
  499. X *                    under SunOS 4.0
  500. X *                - make it work on remote NFS file-systems
  501. X *                - simplify
  502. X */
  503. X
  504. X#ifndef lint
  505. static char rcsid[]="$Header: /usr/src/local/etc/ofiles/RCS/ofiles.c,v 1.8 89/03/21 12:29:30 abe Exp Locker: abe $";
  506. X#endif /* lint */
  507. X
  508. X#include <sys/param.h>
  509. X#include <sys/dir.h>
  510. X#include <sys/signal.h>
  511. X#if ! BSD || BSD < 43
  512. X#include <sys/time.h>
  513. X#endif
  514. X#include <sys/user.h>
  515. X
  516. X#ifdef sun
  517. X#if ! defined _user_h && ! defined _sys_user_h
  518. X#define SunOS 3
  519. X#else
  520. X#define SunOS 4
  521. X#ifdef _sys_user_h
  522. X#define SunOSrel 1
  523. X#else
  524. define SunOSrel 0
  525. X#endif /* _sys_user_h */
  526. X#endif /* _user_h */
  527. X#endif /* sun */
  528. X
  529. X#ifdef sequent
  530. X#define DYNIX
  531. X#endif
  532. X
  533. X#if defined DYNIX || defined sun || defined pyr || defined sony
  534. X#define NFS
  535. X#endif
  536. X
  537. X#ifdef DYNIX
  538. X#define KERNEL
  539. X#include <sys/file.h>
  540. X#include <sys/vnode.h>
  541. X#include <sys/inode.h>
  542. X#undef KERNEL
  543. X#else
  544. X#define KERNEL
  545. X#include <sys/file.h>
  546. X#ifndef NFS
  547. X#include <sys/inode.h>
  548. X#include <sys/mount.h>
  549. X#undef KERNEL
  550. X#else
  551. X#undef KERNEL
  552. X#include <sys/vfs.h>
  553. X#include <rpc/types.h>
  554. X#include <sys/vnode.h>
  555. X#include <ufs/inode.h>
  556. X#include <nfs/nfs.h>
  557. X#include <nfs/rnode.h>
  558. X#include <ufs/mount.h>
  559. X#endif
  560. X#endif
  561. X
  562. X#include <sys/stat.h>
  563. X#ifndef pyr
  564. X#include <machine/pte.h>
  565. X#else
  566. X#include <sys/pte.h>
  567. X#include <sys/immu.h>
  568. X#endif pyr
  569. X
  570. X#if !defined(ultrix) && !defined(sun) && ! defined DYNIX && ! defined pyr
  571. X#include <machine/machparam.h>
  572. X#endif
  573. X#include <sys/proc.h>
  574. X#include <nlist.h>
  575. X#ifndef O_NDELAY
  576. X#include <sys/fcntl.h>
  577. X#endif
  578. X#include <pwd.h>
  579. X#include <fstab.h>
  580. X#include <sys/vmmac.h>
  581. X#include <stdio.h>
  582. X
  583. X#ifdef NFS
  584. struct snode {
  585. X    struct snode *s_next;
  586. X    struct vnode s_vnode;
  587. X    struct vnode *s_realvp;
  588. X    struct vnode *s_bdevvp;
  589. X    u_short s_flag;
  590. X    dev_t s_dev;
  591. X};
  592. X#endif NFS
  593. X
  594. X#if defined sun && SunOS >= 4
  595. X#include <kvm.h>
  596. kvm_t    *kd;
  597. X#endif
  598. X
  599. X#ifdef _nfs_rnode_h        /* _nfs_rnode_h only defined on recent versions of NFS */
  600. X#define r_nfsattr r_attr    /* the names of these fields changed vith new version of NFS */
  601. X#define nfsfattr vattr
  602. X#define na_nodeid va_nodeid
  603. X#endif    /* NFS version */
  604. X
  605. X#ifdef ultrix
  606. X#include <sys/gnode.h>
  607. X#include <sys/gnode_common.h>
  608. X#include <machine/param.h>
  609. X#define i_number g_number
  610. X#endif
  611. X
  612. X#include <sys/socket.h>
  613. X#include <sys/socketvar.h>
  614. X#include <net/route.h>
  615. X#include <netinet/in.h>
  616. X#include <netinet/in_pcb.h>
  617. X#include <netinet/tcp.h>
  618. X#include <netinet/tcp_fsm.h>
  619. X#include <netinet/tcp_timer.h>
  620. X#include <netinet/tcp_var.h>
  621. X
  622. X#define CDIR    01
  623. X#define OFILE    02
  624. X#define RDIR    04
  625. X#define SHFILE    010
  626. X#define EXFILE    020
  627. X#define SOCKET  040
  628. X
  629. X#if (! defined sun || SunOS < 4) && ! defined DYNIX && ! defined pyr
  630. X    /* no more text struct in these systems */
  631. X#include <sys/text.h>
  632. X#endif
  633. X
  634. X#ifdef pyr    /* maybe for all SYS V ? */
  635. X#undef r_lock
  636. X#include <sys/region.h>
  637. X#endif
  638. X    /* defines for unix BSD whitout NFS */
  639. X#define x_ptr x_iptr
  640. X#define node inode
  641. X#define DTYPE_NODE DTYPE_INODE
  642. X#define FSID struct fs *
  643. X#define _fsid i_fs
  644. X#define ISROOT(n) ((n)->i_number == ROOTINO)
  645. X#define ISBDEV(n) (((n)->i_mode&IFMT) == IFBLK)
  646. X#define ISDEV(n) (((n)->i_mode&IFMT) == IFBLK || ((n)->i_mode&IFMT) == IFCHR)
  647. X#define TYPEWORD(n) ((n)->i_mode)
  648. X#define TYPEBITS(m) ((m)&IFMT)
  649. X#define NODETYPE_T unsigned short
  650. X#define TREG IFREG
  651. X#define TDIR IFDIR
  652. X#define TCHR IFCHR
  653. X#define TBLK IFBLK
  654. X
  655. X#ifdef ultrix
  656. X    /* defines for ultrix, i.e. DEC gfs variant of NFS */
  657. X#undef x_ptr
  658. X#undef node
  659. X
  660. X#define x_ptr    x_gptr
  661. X#define node gnode
  662. X#undef FSID
  663. X#define FSID struct mount *
  664. X#define i_fs g_mp
  665. X#undef ISROOT
  666. X#define ISROOT(n) ((n)->g_number == ROOTINO || isroot(n))
  667. X#define i_number g_number
  668. X#define i_mode g_mode
  669. X#define i_rdev g_rdev
  670. X#undef TREG
  671. X#undef TDIR
  672. X#undef TCHR
  673. X#undef TBLK
  674. X#define TREG GFREG
  675. X#define TDIR GFDIR
  676. X#define TCHR GFCHR
  677. X#define TBLK GFBLK
  678. X#include <sys/mount.h>
  679. X#define m_inodp m_gnodp
  680. X#undef NFS    /* ultrix implememtetion of NFS doesn't fit with my defines */
  681. X#if defined P_DYING    /* ultrix 4.1 */
  682. X#define p_flag p_sched
  683. X#endif            /* ultrix 4.1 */
  684. X#endif ultrix
  685. X
  686. X#if defined sun || defined NFS
  687. X    /* defines for unix systems with NFS a la SUN */
  688. X#undef x_ptr
  689. X#undef node
  690. X#undef DTYPE_NODE
  691. X
  692. X#define x_ptr x_vptr
  693. X#define node vnode
  694. X#define DTYPE_NODE DTYPE_VNODE
  695. X
  696. X#undef FSID
  697. X#undef _fsid
  698. X#define FSID struct vfs *
  699. X#define _fsid v_vfsp
  700. X
  701. X#undef ISROOT
  702. X#undef ISBDEV
  703. X#undef ISDEV
  704. X#define ISROOT(n) ((n)->v_flag & VROOT)
  705. X#define ISBDEV(n) (((n)->v_type) == VBLK)
  706. X#define ISDEV(n) (((n)->v_type) == VBLK || ((n)->v_type) == VCHR)
  707. X
  708. X#undef TYPEWORD
  709. X#undef TYPEBITS
  710. X#undef NODETYPE_T
  711. X#undef TREG
  712. X#undef TDIR
  713. X#undef TCHR
  714. X#undef TBLK
  715. X#define TYPEWORD(n) ((n)->v_type)
  716. X#define TYPEBITS(m) m
  717. X#define NODETYPE_T enum vtype
  718. X#define TREG VREG
  719. X#define TDIR VDIR
  720. X#define TCHR VCHR
  721. X#define TBLK VBLK
  722. X
  723. X#endif sun || NFS
  724. X
  725. X#define TYPE(n) (TYPEBITS(TYPEWORD(n)))
  726. X
  727. typedef FSID myfsid_t;
  728. typedef NODETYPE_T nodetype_t;
  729. X
  730. X#define XFILE    0100
  731. X#define MAPPED    0200
  732. X#define MOUNTP    0400
  733. X
  734. X
  735. X#define STR(s) "s"
  736. X
  737. X#if defined sun && SunOS >= 4 
  738. X#include <vm/seg_vn.h>
  739. X#include <vm/seg.h>
  740. X#if SunOSrel > 0
  741. X#include <vm/hat.h>
  742. X#endif
  743. X#include <vm/as.h>
  744. X
  745. X#endif SunOS >= 4
  746. X
  747. X/*
  748. X * PEEK variants:
  749. X *    KM: from /dev/kmem
  750. X *    M:  from /dev/mem
  751. X *    A:  2nd arg is an array, don't take its address, take its size
  752. X *    P:  2nd arg is a pointer, don't take its address, take size of pointed data
  753. X *    E:  return 0 on error instead of aborting
  754. X */
  755. X
  756. X#define KMPEEK(fromwhere, intowhat) \
  757. X    (void)peek(kmem, (ls_t)(fromwhere), (char *)(&intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
  758. X#define KMAPEEK(fromwhere, intowhat) \
  759. X    (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
  760. X#define KMPPEEK(fromwhere, intowhat) \
  761. X    (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
  762. X#define MPPEEK(fromwhere, intowhat) \
  763. X    (void)peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
  764. X#define EKMAPEEK(fromwhere, intowhat) \
  765. X    peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 1)
  766. X#define EMPPEEK(fromwhere, intowhat) \
  767. X    peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 1)
  768. X
  769. X#if !defined NFS && ! defined ROOTINO
  770. X#ifdef ultrix
  771. X#include <ufs/fs.h>
  772. X#else
  773. X#include <sys/fs.h>
  774. X#endif
  775. X#endif
  776. X
  777. char *namelist;
  778. char *corefile;
  779. int k_opt = 0;
  780. X#ifdef pyr
  781. int dflg = 0;
  782. X#endif pyr
  783. int n_opt = 0;
  784. X
  785. X#if defined    ultrix || ( defined sun && SunOS < 4)
  786. X#define    ls_t    long
  787. X#else
  788. X#define ls_t    off_t
  789. X#endif
  790. X
  791. X#ifdef    sun
  792. char    *sprintf();
  793. X#endif
  794. X
  795. ls_t lseek(), vtophys();
  796. X
  797. X#ifdef    ultrix
  798. void exit(), nlist(), perror();
  799. X#endif
  800. X
  801. int nproc;        /* number of entries in proc table         */
  802. int mem;        /* fd for /dev/mem                */
  803. int kmem;
  804. int swap;        /* fd for /dev/swap                */
  805. struct proc  *procbase, *procNPROC;
  806. int ppid = -1;        /* previously display PID */
  807. X
  808. int pids_only = 0;    /* if non-zero, only output process ids    */
  809. int iflag = 0;        /* i-numbers wanted */
  810. X
  811. char *progname;
  812. struct nlist nl[] = {
  813. X#ifndef mips
  814. X#define SYM(s) STR(_/**/s)
  815. X#else
  816. X#define SYM(s) STR(s)
  817. X#endif
  818. X#define    X_PROC        0
  819. X    { SYM(proc) },
  820. X#define X_PROCNPROC     1
  821. X    { SYM(procNPROC) },
  822. X#define X_SYSMAP    2
  823. X    { SYM(Sysmap) },
  824. X#define    SFIL        3
  825. X    {  SYM(file)  },
  826. X#define    SNFILE        4
  827. X    {  SYM(nfile)  },
  828. X#define X_U        5
  829. X#if sun && SunOS >= 4 && SunOSrel >= 1
  830. X    { SYM(uunix) },
  831. X#else
  832. X    { SYM(u) },
  833. X#endif /* SunOS >= 4.1 */
  834. X#if defined NFS
  835. X#define X_ROOTVFS    6
  836. X    { SYM(rootvfs) },
  837. X#else
  838. X#define X_MOUNT        6
  839. X    { SYM(mount) },
  840. X#endif
  841. X#ifdef NFS
  842. X#define X_UFSVNOPS    7
  843. X    { SYM(ufs_vnodeops) },
  844. X#define X_NFSVNOPS    8
  845. X    { SYM(nfs_vnodeops) },
  846. X#define X_SPECVNOPS    9
  847. X    { SYM(spec_vnodeops) },
  848. X#endif NFS
  849. X    { "" }
  850. X};
  851. X
  852. X#if sun && SunOS >= 4 && SunOSrel >= 1
  853. X#define U_ADDR uunix
  854. struct user *uunix;
  855. struct file **ofilep;
  856. struct file *ofile_arr[NOFILE];
  857. int nofile;
  858. X#undef NOFILE
  859. X#define NOFILE nofile
  860. X#define ofile(x) ofilep[x]
  861. X#else
  862. X#define U_ADDR ((struct user *)(nl[X_U].n_value))
  863. X#endif
  864. X
  865. X#ifdef pyr
  866. X#define DELTA_U    ((char *)u -(char *)U_ADDR)
  867. X#define ofile(x) (((struct file **)(((char *)(u->u_ofile))+DELTA_U))[x])
  868. X#endif
  869. X
  870. X#ifdef    DYNIX
  871. X#define ofile(x) u->u_lofile[x].of_file
  872. X#undef NOFILE
  873. X#define NOFILE u->u_nofile
  874. X#endif
  875. X
  876. X#ifndef ofile
  877. X    /* normal case, "standard " unix */
  878. X#define ofile(x) u->u_ofile[x]
  879. X#endif /* normal case */
  880. X
  881. int debug;
  882. char *filename, *fsname;
  883. struct node *argnodep, argnode;
  884. dev_t argdev;
  885. nodetype_t argtype;
  886. X
  887. onalarm() {}
  888. X
  889. X#ifdef ultrix
  890. X
  891. isroot(np)
  892. struct node *np;
  893. X{
  894. X    struct node *mp;
  895. X    KMPEEK(&(np->g_mp->m_gnodp), mp);
  896. X    return (mp == argnodep);
  897. X}
  898. X#endif ultrix
  899. X
  900. X#if (defined ultrix || defined sony) && defined mips
  901. uread(from, to)
  902. unsigned int from, *to;
  903. X{
  904. X    struct pte *paddr;
  905. X    struct proc *procp;
  906. X#if 0
  907. X    int pte;
  908. X#else
  909. X    struct pte pte;
  910. X#endif
  911. X    short pid, mypid;
  912. X    mypid = getpid();
  913. X    for (procp = procbase + 2; procp < procNPROC; ++procp) {
  914. X        KMPEEK(&(procp->p_pid), pid);
  915. X        if (pid == mypid) goto found;
  916. X    }
  917. X    error("My pid is not in proc table !\n");
  918. found:
  919. X    KMPEEK(&(procp->p_addr), paddr);
  920. X    KMPEEK(&paddr[(from-UADDR)>>PGSHIFT], pte);
  921. X#if 0
  922. X    MPPEEK((pte&PG_PFNUM) | (from & PGOFSET), to);
  923. X#else
  924. X    MPPEEK((pte.pg_pfnum << PGSHIFT) | (from & PGOFSET), to);
  925. X#endif
  926. X}
  927. X
  928. X
  929. X#endif 
  930. X
  931. ismountdev(s)
  932. char *s;
  933. X{
  934. X    register struct fstab *fs;
  935. X    
  936. X    if ((fs = getfsspec(s)) != NULL) {
  937. X        fsname = fs->fs_file;
  938. X        return 1;
  939. X    }
  940. X    return 0;
  941. X}
  942. X
  943. getmountdev(s)
  944. char *s;
  945. X{
  946. X    register struct fstab *fs;
  947. X
  948. X    if ((fs = getfsfile(s)) != NULL)
  949. X        filename = fs->fs_spec;
  950. X}
  951. X
  952. struct proc p;
  953. X
  954. ino_t inum;
  955. X#ifdef NFS
  956. struct snode *vdata;
  957. X#endif
  958. X
  959. int type;
  960. X
  961. main(argc, argv)
  962. X    int     argc;
  963. X    char    *argv[];
  964. X{
  965. X
  966. X    struct user *u, *getuser();
  967. X    struct proc *procp;
  968. X    register int filen, flags;
  969. X    char *getsockfp(), *rindex();
  970. X    struct file *fp;
  971. X    int ax, err, findf, nmct;
  972. X    char *ap;
  973. X    int exitval = 0;
  974. X    struct mount *mountp;
  975. X
  976. X#ifdef    lint
  977. X/*
  978. X * The following code satisfies lint for KERNEL symbols.
  979. X * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
  980. X * and ULTRIX 2.2, using the lint libraries of the systems at the
  981. X * Purdue University Computing Center.
  982. X */
  983. X#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  984. X    long lintlong;
  985. X#endif
  986. X#ifdef    ultrix
  987. X    struct nch *lintnch;
  988. X    float lintfloat;
  989. X#endif
  990. X#if    !defined(DYNIX)
  991. X    file = fileNFILE = NULL;
  992. X    fp = file;
  993. X    fp = fileNFILE;
  994. X    nfile = 0;
  995. X    filen = nfile;
  996. X#endif
  997. X#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  998. X    inode = inodeNINODE = rootdir = NULL;
  999. X    i = inode;
  1000. X    i = inodeNINODE;
  1001. X    i = rootdir;
  1002. X    ninode = 0;
  1003. X    nextinodeid = 0l;
  1004. X    lintlong = nextinodeid;
  1005. X    nextinodeid = lintlong;
  1006. X    filen = ninode;
  1007. X#endif
  1008. X#if defined sun && SunOS >= 4
  1009. X    tcp_ttl = 0;
  1010. X    filen  = tcp_ttl;
  1011. X#endif
  1012. X#ifdef    ultrix
  1013. X    nch = NULL;
  1014. X    lintnch = nch;
  1015. X    nch = lintnch;
  1016. X    nchsize = 0;
  1017. X    filen = nchsize;
  1018. X    tcp_alpha = tcp_beta = 0.0;
  1019. X    lintfloat = tcp_alpha;
  1020. X    lintfloat = tcp_beta;
  1021. X    tcp_alpha = lintfloat;
  1022. X#endif
  1023. X#endif    /* lint */
  1024. X
  1025. X    if ((progname = rindex(argv[0], '/')))
  1026. X        progname++;
  1027. X    else
  1028. X        progname = argv[0];
  1029. X
  1030. X    if (argc == 1) {
  1031. X
  1032. usage:
  1033. X
  1034. X#ifdef    DYNIX
  1035. X        (void) fprintf(stderr,
  1036. X            "usage: %s [-D ] [-k nlist core] [-n] [-p] [-d|-n|-p]  names\n",
  1037. X            progname);
  1038. X#else
  1039. X        (void) fprintf(stderr,
  1040. X            "usage: %s [-D ] [-n] [-p] [-d|-n|-p] names\n", progname);
  1041. X#endif
  1042. X        (void) fprintf(stderr, "\t-D    = select verbose debugging output\n");
  1043. X#ifdef    DYNIX
  1044. X        (void) fprintf(stderr,
  1045. X            "\t-k    = use specified nlist and core files\n");
  1046. X#endif
  1047. X        (void) fprintf(stderr,
  1048. X            "\t-n    = interpret names as network connection, hexadecimal,\n");
  1049. X        (void) fprintf(stderr,
  1050. X            "\t        Protocol Control Block (PCB) addresses, as supplied\n");
  1051. X        (void) fprintf(stderr,
  1052. X            "\t        by netstat's -A option\n");
  1053. X        (void) fprintf(stderr, "\t-p    = print only process IDs\n");
  1054. X        (void) fprintf(stderr,
  1055. X            "\tnames = file names or PCB addresses\n");
  1056. X        (void) fprintf(stderr, "\t-d\n\t-m\n\t-f      force name to be considered respectiveley\n");
  1057. X        (void) fprintf(stderr, "\t\t as a device, mount point or regular file\n");
  1058. X        exit(exitval);
  1059. X    }
  1060. X
  1061. X    /* check for switches */
  1062. X    for (err = 0, ax = 1; ax < argc; ax++) {
  1063. X        ap = argv[ax];
  1064. X        if (*ap++ != '-')
  1065. X            break;
  1066. X        while (*ap) {
  1067. X            type = 0;
  1068. X            switch (*ap++) {
  1069. X
  1070. X            case 'D':
  1071. X                debug = 1;
  1072. X                break;
  1073. X#if defined DYNIX || defined pyr
  1074. X            case 'k':
  1075. X                if ((ax + 2) >= argc) {
  1076. X                    (void) fprintf(stderr,
  1077. X                        "%s: no nlist/core after -k\n",
  1078. X                        progname);
  1079. X                    err++;
  1080. X                } else {
  1081. X                    namelist = argv[++ax];
  1082. X                    corefile = argv[++ax];
  1083. X                    k_opt = 1;
  1084. X#ifdef pyr
  1085. X                    if (ap[1] == 'd')
  1086. X                        dflg = 1;
  1087. X#endif pyr
  1088. X                    continue;
  1089. X                }
  1090. X                break;
  1091. X#endif DYNIX || pyr
  1092. X            case 'n':
  1093. X                n_opt++;
  1094. X                break;
  1095. X
  1096. X            case 'p':
  1097. X                pids_only = 1;
  1098. X                break;
  1099. X            case 'i':
  1100. X                iflag = 1;
  1101. X                break;
  1102. X
  1103. X            case 'm':
  1104. X            case 'f':
  1105. X            case 'd':
  1106. X                type = ap[-1];
  1107. X                break;
  1108. X            default:
  1109. X                (void) fprintf(stderr,
  1110. X                    "%s: unknown switch - %c\n",
  1111. X                    progname, *(ap - 1));
  1112. X                err++;
  1113. X            }
  1114. X        }
  1115. X    }
  1116. X    if (ax >= argc) {
  1117. X        (void) fprintf(stderr, "%s: no names specified\n", progname);
  1118. X        err++;
  1119. X    }
  1120. X    if (err) {
  1121. X        exitval = 1;
  1122. X        goto usage;
  1123. X    }
  1124. X
  1125. X#if defined sun && SunOS >= 4
  1126. X        if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
  1127. X        (void) fprintf(stderr, "%s: can't access memory: ",
  1128. X            progname);
  1129. X            perror ("");
  1130. X        exit(1);
  1131. X    }
  1132. X#endif
  1133. X    if ((mem = open("/dev/mem", 0)) < 0) {
  1134. X        (void) fprintf(stderr, "%s: /dev/mem: ", progname);
  1135. X        perror("");
  1136. X        exit(1);
  1137. X    }
  1138. X    if (k_opt) {
  1139. X        if ((kmem = open(corefile, 0)) < 0) {
  1140. X            (void) fprintf(stderr, "%s: %s: ",
  1141. X                progname, corefile);
  1142. X            perror("");
  1143. X            exit(1);
  1144. X        }
  1145. X        mem = kmem;
  1146. X#ifdef pyr
  1147. X        if (dflg)
  1148. X            setdump();
  1149. X#endif pyr
  1150. X    } else {
  1151. X        if ((kmem = open("/dev/kmem", 0)) < 0) {
  1152. X            (void) fprintf(stderr, "%s: /dev/kmem: ", progname);
  1153. X            perror("");
  1154. X            exit(1);
  1155. X        }
  1156. X    }
  1157. X#ifndef pyr
  1158. X    if (!k_opt) 
  1159. X        if ((swap = open("/dev/drum", 0)) < 0) {
  1160. X            (void) fprintf(stderr, "%s: /dev/drum: ", progname);
  1161. X            perror("");
  1162. X            exit(1);
  1163. X        }
  1164. X#endif pyr
  1165. X    getsyms();
  1166. X
  1167. X    for (err = 0, nmct = argc - ax; ax < argc; ax++) {
  1168. X        /* if -n, then arg is a PCB */
  1169. X        if (n_opt) {
  1170. X            if ((filename = getsockfp(argv[ax], &fp)) == NULL) {
  1171. X                err++;
  1172. X                continue;
  1173. X            }
  1174. X            fsname = "";
  1175. X        } else {
  1176. X            int argfd;
  1177. X            char buf[100];
  1178. X
  1179. X            filename = argv[ax];
  1180. X            fsname = filename;
  1181. retry:
  1182. X            signal(SIGALRM,onalarm);
  1183. X            alarm(1);
  1184. X            argfd = open(fsname, O_RDONLY|O_NDELAY);
  1185. X            alarm(0);
  1186. X            if (argfd == -1) {
  1187. X                extern int errno;
  1188. X                extern char *sys_errlist[];
  1189. X                struct stat bufstat;
  1190. X                if (stat(fsname, &bufstat) != -1)
  1191. X                    switch (bufstat.st_mode & IFMT) {
  1192. X                        case IFBLK:
  1193. X                            argtype = TBLK;
  1194. X                            break;
  1195. X                        case IFCHR:
  1196. X                            argtype = TCHR;
  1197. X                            break;    
  1198. X                        default:
  1199. X                            goto bad;
  1200. X                    }
  1201. X                else
  1202. X                    goto bad;
  1203. X                argdev = bufstat.st_rdev;
  1204. X                type = 'd';
  1205. X                goto skip;
  1206. bad:
  1207. X                (void) sprintf(buf, "open failed for %s (%s)\n", fsname, sys_errlist[errno]);
  1208. X                error(buf);
  1209. X
  1210. X            }
  1211. X#if defined pyr || defined sun && SunOS >= 4 && SunOSrel >=1
  1212. X#define OFILEPTR
  1213. X            {
  1214. X            struct file **ofp;
  1215. X#if defined sun
  1216. X            KMPEEK(nl[X_U].n_value, uunix);
  1217. X#endif
  1218. X            KMPEEK(&(U_ADDR->u_ofile), ofp);
  1219. X            KMPEEK(ofp+argfd, fp);
  1220. X            }
  1221. X#endif OFILEPTR
  1222. X
  1223. X#if defined mips && (defined ultrix || defined sony)
  1224. X    /* ultrix & sony mips have no access via kmem to its own user struct ! */
  1225. X            uread(&((U_ADDR->u_ofile)[argfd]), &fp);
  1226. X#endif
  1227. X
  1228. X
  1229. X#if !defined OFILEPTR && !((defined ultrix || defined sony) && defined mips)
  1230. X    /* the "normal case " */
  1231. X            KMPEEK(U_ADDR->u_ofile+argfd, fp);
  1232. X#endif /* normal case */
  1233. X            KMPEEK(&(fp->f_data), argnodep);
  1234. X            KMPEEK(argnodep, argnode);
  1235. X            (void)close(argfd);
  1236. X            switch(type) {
  1237. X                case 0:
  1238. X                    if (ISROOT(&argnode)) {
  1239. X                        type = 'm';
  1240. X                        getmountdev(filename);
  1241. X                    } else if (ISDEV(&argnode))
  1242. X                        if (ismountdev(fsname)) {
  1243. X                            type = 'm';
  1244. X                            goto retry;
  1245. X                        } else {
  1246. X                            type = 'd';
  1247. X                            fsname = "";
  1248. X                        }
  1249. X                    else {
  1250. X                        type = 'f';
  1251. X                        fsname = "";
  1252. X                    }
  1253. X                    break;
  1254. X                case 'f':
  1255. X                    switch(TYPE(&argnode)) {
  1256. X                        case TREG:
  1257. X                        case TDIR:
  1258. X                        case TCHR:
  1259. X                        case TBLK:
  1260. X                            break;
  1261. X                        default:
  1262. X                            (void)sprintf(buf,
  1263. X                                "invalid %s type for arg type '%c' arg %s\n",
  1264. X                                STR(node),
  1265. X                                type,
  1266. X                                argv[ax]);
  1267. X                            error(buf);
  1268. X                    }
  1269. X                    break;
  1270. X                case 'm':
  1271. X                    if (!ISROOT(&argnode)) {
  1272. X                        if (ismountdev(fsname))
  1273. X                            goto retry;
  1274. X                        (void)sprintf(buf,
  1275. X                            "%s is not a root\n",
  1276. X                            fsname);
  1277. X                        error(buf);
  1278. X                    }
  1279. X                    if (fsname == filename)
  1280. X                        getmountdev(filename);
  1281. X                    break;
  1282. X                case 'd':
  1283. X                    if(!ISDEV(&argnode)) {
  1284. X                        (void)sprintf(buf,
  1285. X                            "%s is not a device\n",
  1286. X                            filename);
  1287. X                        error(buf);
  1288. X                    }
  1289. X                    fsname = "";
  1290. X                    break;
  1291. X            }
  1292. X            if (type == 'd')
  1293. X#ifdef NFS
  1294. X                KMPEEK(&(((struct snode *)(argnode.v_data))->s_dev), argdev);
  1295. X#else
  1296. X                argdev = argnode.i_rdev;
  1297. X#endif NFS
  1298. X                argtype = TYPE(&argnode);
  1299. X        }
  1300. X        if (iflag && type == 'f') {
  1301. X#ifdef NFS
  1302. X            struct node *i;
  1303. X
  1304. X            if (ISDEV(&argnode)) {
  1305. X                KMPEEK(&(((struct snode *)argnode.v_data)->s_realvp), i);
  1306. X                KMPEEK(&(i->v_data), vdata);
  1307. X            } else {
  1308. X                if ((int)argnode.v_op == nl[X_UFSVNOPS].n_value)
  1309. X                    KMPEEK(&(((struct inode *)argnode.v_data)->i_number), inum);
  1310. X                else if ((int)argnode.v_op == nl[X_NFSVNOPS].n_value)
  1311. X                    KMPEEK(&(((struct rnode *)argnode.v_data)->r_nfsattr.na_nodeid), inum);
  1312. X                else
  1313. X                    inum = 0;
  1314. X            }
  1315. X#else
  1316. X            inum = argnode.i_number;
  1317. X#endif
  1318. X        }
  1319. skip:
  1320. X        if (! pids_only) {
  1321. X            (void) printf("%s\t%s", filename, fsname);
  1322. X            if (!n_opt) {
  1323. X                if (type == 'f')
  1324. X                    if (TYPE(&argnode) == TDIR)
  1325. X                        (void) printf(" (directory)");
  1326. X                    else
  1327. X                        (void) printf(" (regular file)");
  1328. X                else if (type == 'm')
  1329. X                    (void) printf(" (mount point)");
  1330. X                else
  1331. X                    (void) printf(" (device)");
  1332. X                    
  1333. X            }
  1334. X            (void) printf("\n%-8.8s  %5s  %-6.6s  FD  %-14.14s",
  1335. X                "USER", "PID", "TYPE", "CMD");
  1336. X            if (!n_opt && iflag)
  1337. X                (void) printf("  INODE");
  1338. X            (void) printf("\n");
  1339. X        }
  1340. X        if (!n_opt) {
  1341. X            struct node *i;
  1342. X#if defined NFS
  1343. X            struct vfs *vfsp;
  1344. X            KMPEEK(nl[X_ROOTVFS].n_value, vfsp);
  1345. X            for (; vfsp; KMPEEK(&(vfsp->vfs_next), vfsp)) {
  1346. X                KMPEEK(&(vfsp->vfs_vnodecovered), i);
  1347. X                if(!i) continue;
  1348. X                if (check(i, type))
  1349. X                    gotone(0,0,-1,MOUNTP,i);
  1350. X            }
  1351. X#else
  1352. X            mountp = (struct mount *)nl[X_MOUNT].n_value;
  1353. X            for (;;) {
  1354. X                KMPEEK(&(mountp->m_inodp), i);
  1355. X                if (!i) break;
  1356. X                if (check(i, type))
  1357. X                    gotone(0,0,-1,MOUNTP,i);
  1358. X                ++mountp;
  1359. X            }
  1360. X#endif NFS
  1361. X        }
  1362. X
  1363. X        for (procp = procbase, findf = 0; procp < procNPROC; ++procp) {
  1364. X            KMPEEK(procp, p);
  1365. X            flags = 0;
  1366. X            if (p.p_stat == 0 || p.p_stat == SZOMB) 
  1367. X                continue;
  1368. X#if defined sun && SunOS >= 4
  1369. X            u = kvm_getu(kd, &p);
  1370. X#if SunOSrel >= 1
  1371. X            getuofiles(u, p.p_segu);
  1372. X#endif
  1373. X#else
  1374. X            u = getuser(&p);
  1375. X#endif
  1376. X
  1377. X            if ( u == (struct user *)NULL)
  1378. X                continue;
  1379. X            if (debug)
  1380. X                (void) printf("pid %d uid %d cmd %s\n", p.p_pid,
  1381. X                    p.p_uid, u->u_comm);
  1382. X            if (!n_opt) {
  1383. X                struct node *txtnode;
  1384. X
  1385. X                if (check(u->u_rdir, type)) {
  1386. X                    gotone(u, &p, -1, RDIR, u->u_rdir);
  1387. X                    findf++;
  1388. X                }
  1389. X                if (check(u->u_cdir, type)) {
  1390. X                    gotone(u, &p, -1, CDIR, u->u_cdir);
  1391. X                    findf++;
  1392. X                }
  1393. X        /* check text files */
  1394. X#if (! defined sun || SunOS < 4) && !defined pyr
  1395. X#ifndef DYNIX
  1396. X                if (p.p_textp) {
  1397. X                    KMPEEK(&(p.p_textp->x_ptr), txtnode);
  1398. X                    if (check(txtnode, type)) {
  1399. X                        gotone(u, &p, -1, XFILE, txtnode);
  1400. X                        findf++;
  1401. X                    }
  1402. X                }
  1403. X#endif DYNIX
  1404. X#endif
  1405. X#ifdef pyr
  1406. X                {
  1407. X                    struct pregion *prp = p.p_region;
  1408. X                    struct region *rp;
  1409. X                    struct node *lastv = 0;
  1410. X                    int nreg;
  1411. X
  1412. X                    for (nreg = 0; nreg <= p.p_nregion; ++nreg) {
  1413. X                        KMPEEK(&(prp->p_reg), rp);
  1414. X                        KMPEEK(&(rp->r_vptr), txtnode);
  1415. X                        if (txtnode == lastv) continue;
  1416. X                        if (check(txtnode, type)) {
  1417. X                            gotone(u, &p, -1, XFILE, txtnode);
  1418. X                            findf++;
  1419. X                        }
  1420. X                        lastv = txtnode;
  1421. X                    }
  1422. X                }
  1423. X#endif pyr
  1424. X#if defined sun && SunOS >= 4
  1425. X        /* in SunOS >= 4 and DYNIX, text files are mapped files */
  1426. X                if (p.p_as) {
  1427. X                    struct seg *segp, *segnext;
  1428. X                    struct  segvn_data *svd;
  1429. X                    struct vnode *lastv = 0;
  1430. X
  1431. X                    KMPEEK(&(p.p_as->a_segs), segp);
  1432. X                    if (!segp) goto noseg;
  1433. X                    segnext = segp;
  1434. X                    do {
  1435. X                        KMPEEK(&((struct  segvn_data *)(segnext->s_data)), svd);
  1436. X                        if (!svd) continue;
  1437. X                        KMPEEK(&(svd->vp), txtnode);
  1438. X                        if(txtnode == lastv) continue;
  1439. X#if defined sun
  1440. X                        if(((int)txtnode&0xff00000) != 0xff00000
  1441. X) continue;
  1442. X#endif sun
  1443. X                        if (check(txtnode, type)) {
  1444. X                            gotone(u, &p, -1, MAPPED, txtnode);
  1445. X                            findf++;
  1446. X                            lastv = txtnode;
  1447. X                        }
  1448. X                        
  1449. X                    } while(KMPEEK(&((struct  segvn_data *)(segnext->s_next)), segnext),
  1450. X                        segnext != segp);
  1451. X                    noseg: ;
  1452. X                }
  1453. X#endif SunOS < 4
  1454. X            }
  1455. X            for (filen = 0; filen < NOFILE; filen++)
  1456. X            {
  1457. X                struct file f;
  1458. X
  1459. X                flags = 0;
  1460. X                if (n_opt) {
  1461. X                    if (ofile(filen) != fp)
  1462. X                        continue;
  1463. X                } else {
  1464. X                    if (ofile(filen) == NULL)
  1465. X                        continue;
  1466. X                }
  1467. X
  1468. X                KMPEEK(ofile(filen), f);
  1469. X
  1470. X                if (f.f_count > 0) {
  1471. X                    if (n_opt && f.f_type == DTYPE_SOCKET) {
  1472. X                        gotone(u, &p, filen, SOCKET, 0);
  1473. X                        findf++;
  1474. X                        continue;
  1475. X                    }
  1476. X                    if (f.f_type != DTYPE_NODE)
  1477. X                        continue;
  1478. X
  1479. X                    if (check((struct node *)f.f_data,
  1480. X                        type)) {
  1481. X                        flags |= OFILE;
  1482. X                        if (f.f_flag & FEXLOCK) {
  1483. X                            flags |= EXFILE;
  1484. X                        }
  1485. X                        if (f.f_flag & FSHLOCK) {
  1486. X                            flags |= SHFILE;
  1487. X                        }
  1488. X                        gotone(u, &p, filen, flags, (struct node *)f.f_data);
  1489. X                        findf++;
  1490. X                    }
  1491. X                }
  1492. X            }
  1493. X        }
  1494. X        if (findf)
  1495. X            nmct--;
  1496. X        if (! pids_only) {
  1497. X                (void) printf("\n");
  1498. X            (void) fflush(stdout);
  1499. X        }
  1500. X    }
  1501. X    if (pids_only && ppid != -1) {
  1502. X        (void) printf("\n");
  1503. X        (void) fflush(stdout);
  1504. X    }
  1505. X    exitval = (err || nmct) ? 1 : 0;
  1506. X    exit(exitval);
  1507. X}
  1508. X
  1509. X
  1510. X/*
  1511. X * print the name of the user owning process "p" and the pid of that process
  1512. X */
  1513. gotone(u, p, fd, f, i)
  1514. X    struct user *u;
  1515. X    struct proc *p;
  1516. X    int fd;
  1517. X    int f;
  1518. X    struct node *i;
  1519. X{
  1520. X    char *ty, tybuf[8], *strcat(), *strcpy();
  1521. X    struct passwd *getpwuid();
  1522. X    register struct passwd *pw;
  1523. X
  1524. X    /* only print pids and return */
  1525. X    if (pids_only) {
  1526. X        if (!p) return;
  1527. X        if (ppid != p->p_pid) {
  1528. X            if (ppid != -1)
  1529. X                (void) printf(" ");
  1530. X            (void) printf("%d", p->p_pid);
  1531. X            (void) fflush(stdout);
  1532. X            ppid = p->p_pid;
  1533. X        }
  1534. X        return;
  1535. X    }
  1536. X    if (p) {
  1537. X        pw = getpwuid((int)p->p_uid);
  1538. X        if (pw)
  1539. X            (void) printf("%-8.8s  ", pw->pw_name );
  1540. X        else
  1541. X            (void) printf("%-8d  ", p->p_uid);
  1542. X        (void) printf("%5d  ", p->p_pid);
  1543. X        if (f & OFILE) {
  1544. X            (void) strcpy(tybuf, "file");
  1545. X            ty = tybuf;
  1546. X            if (f & SHFILE)
  1547. X                (void) strcat(ty, "/s");
  1548. X            else if (f & EXFILE)
  1549. X                (void) strcat(ty, "/x");
  1550. X        } else if (f & CDIR)
  1551. X            ty = "cwd";
  1552. X        else if (f & RDIR)
  1553. X            ty = "rdir";
  1554. X        else if (f & SOCKET)
  1555. X            ty = "sock";
  1556. X#if SunOS < 4
  1557. X        else if (f & XFILE)
  1558. X            ty = "text";
  1559. X#else /* SunOS >= 4 */
  1560. X        else if (f & MAPPED)
  1561. X            ty = "mapped";
  1562. X#endif /* SunOS */
  1563. X        else
  1564. X            ty = "";
  1565. X    } else {
  1566. X        printf("                 ");
  1567. X        if (f & MOUNTP)
  1568. X        ty = "mntpnt";
  1569. X    }
  1570. X    (void) printf("%-6.6s  ", ty);
  1571. X    if (fd >= 0)
  1572. X        (void) printf("%2d  ", fd);
  1573. X    else
  1574. X        (void) printf("    ");
  1575. X    (void) printf("%-14.14s", u?u->u_comm:"");
  1576. X    if (iflag && i) {
  1577. X        if (type != 'f') {
  1578. X#ifdef NFS
  1579. X            struct vnodeops *vopp;
  1580. X
  1581. X            if (type != 'd')
  1582. X                KMPEEK(&(i->v_data), vdata);
  1583. X            KMPEEK(&(i->v_op), vopp);
  1584. X            if ((int)vopp == nl[X_UFSVNOPS].n_value)
  1585. X                KMPEEK(&(((struct inode *)vdata)->i_number), inum);
  1586. X            else if ((int)vopp == nl[X_NFSVNOPS].n_value)
  1587. X                KMPEEK(&(((struct rnode *)vdata)->r_nfsattr.na_nodeid), inum);
  1588. X            else if ((int)vopp == nl[X_SPECVNOPS].n_value) {
  1589. X                KMPEEK(&(vdata)->s_realvp, i);
  1590. X                KMPEEK(&(i->v_data), vdata);
  1591. X                KMPEEK(&(((struct inode *)vdata)->i_number), inum);
  1592. X            } else
  1593. X                inum = 0;
  1594. X#else
  1595. X            KMPEEK(&(i->i_number), inum);
  1596. X#endif
  1597. X        }
  1598. X        printf("  %5d", inum);
  1599. X    }
  1600. X
  1601. X    (void) printf("\n");
  1602. X    return;
  1603. X}
  1604. X
  1605. X/*
  1606. X * is [igv]node "i"
  1607. X      - on the filesystem of argnode when type == 'm'
  1608. X     - identical to argnode when type = 'f'
  1609. X     - the same device as argnode when type == 'd'
  1610. X   ?
  1611. X   returns TRUE or FALSE 
  1612. X */
  1613. X
  1614. check(i, type)
  1615. X    struct node *i;
  1616. X{
  1617. X    myfsid_t fsid;
  1618. X    dev_t dev;
  1619. X    nodetype_t tword;
  1620. X
  1621. X    if (type == 'f') return (i == argnodep);
  1622. X    if (i == (struct node *)NULL)
  1623. X        return 0;
  1624. X    if (type == 'm') {
  1625. X        KMPEEK(&(i->_fsid), fsid);
  1626. X        return (argnode._fsid == fsid);
  1627. X    }
  1628. X    KMPEEK(&TYPEWORD(i),tword);
  1629. X    if (TYPEBITS(tword) != argtype) return 0;
  1630. X#ifndef NFS
  1631. X    KMPEEK(&(i->i_rdev), dev);
  1632. X#else
  1633. X    KMPEEK(&(i->v_data), vdata);
  1634. X    KMPEEK(&(vdata->s_dev), dev);
  1635. X#endif
  1636. X    return (argdev == dev);
  1637. X}
  1638. X
  1639. X
  1640. X#if !defined(sun) || SunOS < 4
  1641. X/* 
  1642. X * get user page for proc "p" from core or swap
  1643. X * return pointer to user struct
  1644. X */
  1645. X#ifdef    DYNIX
  1646. struct user *
  1647. getuser(p)
  1648. X    struct proc *p;
  1649. X{
  1650. X    int btr;
  1651. X    ls_t sp;
  1652. X    static struct user *u = NULL;
  1653. X    char *valloc();
  1654. X
  1655. X    if (u == NULL) {
  1656. X        if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
  1657. X            (void) fprintf(stderr,
  1658. X                "%s: can't allocate space for user structure\n",                progname);
  1659. X            exit(1);
  1660. X        }
  1661. X    }
  1662. X    btr = ctob(UPAGES);
  1663. X    if ((p->p_flag & SLOAD) == 0) {
  1664. X        if (k_opt)
  1665. X            return (struct user *)NULL;
  1666. X        sp = (ls_t) dtob(p->p_swaddr);
  1667. X        if (lseek(swap, sp, 0) != sp) {
  1668. X            if (debug) {
  1669. X                (void) fprintf(stderr,
  1670. X                    "%s: error seeking to swap for %d: ",
  1671. X                    progname, p->p_pid);
  1672. X                perror("");
  1673. X            }
  1674. X            return (struct user *)NULL;
  1675. X        }
  1676. X        if (read(swap, (char*)u, btr) != btr) {
  1677. X            if (debug) {
  1678. X                (void) fprintf(stderr,
  1679. X                    "%s: error reading swap for %d: ",
  1680. X                    progname, p->p_pid);
  1681. X                perror("");
  1682. X            }
  1683. X            return (struct user *)NULL;
  1684. X        }
  1685. X        if (debug)
  1686. X            (void) printf("read swap\n");
  1687. X    } else {
  1688. X        KMPPEEK(p->p_uarea, u);
  1689. X    }
  1690. X    return u;
  1691. X}
  1692. X#endif
  1693. X
  1694. X#ifdef pyr
  1695. struct user *
  1696. getuser(p)
  1697. X    struct proc *p;
  1698. X{
  1699. X    static union uuser {
  1700. X        struct user u_user;
  1701. X        char u_bytes[UPAGES*NBPG];
  1702. X    } uuser;
  1703. X
  1704. X    if (readublk(p->p_pid, &uuser))
  1705. X        return 0;
  1706. X    else
  1707. X        return &uuser.u_user;
  1708. X}
  1709. X
  1710. X#endif pyr
  1711. X
  1712. X#if ! defined DYNIX && ! defined pyr
  1713. struct user *
  1714. getuser(p)
  1715. X    struct proc *p;
  1716. X{
  1717. X#define USERPAGES ((sizeof (struct user) + NBPG -1)/NBPG)
  1718. X    struct pte mypgtbl[USERPAGES];
  1719. X    int upage;
  1720. X    ls_t sp;
  1721. X    typedef struct { char bytes[NBPG] } page;
  1722. X    page *up;
  1723. X    static union uuser {
  1724. X        struct user u_user;
  1725. X        char u_bytes[USERPAGES*NBPG];
  1726. X    } uuser;
  1727. X#define User uuser.u_user
  1728. X
  1729. X    /* easy way */
  1730. X    if ((p->p_flag & SLOAD) == 0) {
  1731. X        if (k_opt)
  1732. X            return (struct user *)NULL;
  1733. X#if defined ultrix && defined P_DYING        /* ultrix 4.1 */
  1734. X        if (p->p_smap == 0)
  1735. X            return (struct user *)NULL;
  1736. X        {
  1737. X        struct dmap l_dmap;
  1738. X        int ublkno;
  1739. X        KMPEEK(p->p_smap, l_dmap);
  1740. X        KMPEEK(l_dmap.dm_ptdaddr, ublkno);
  1741. X        sp = (ls_t)dtob(ublkno);
  1742. X        }
  1743. X#else
  1744. X        sp = (ls_t)dtob(p->p_swaddr);
  1745. X#endif /* ultrix 4.1 */
  1746. X        if(!peek(swap,  sp, (char *)&User, sizeof(union uuser),
  1747. X            "swapped user page(s)", __LINE__, -1))
  1748. X            return (struct user *)NULL;
  1749. X        if (debug)
  1750. X            (void) printf("read swap\n");
  1751. X    } else {     /* boo */
  1752. X        /* now get this user's page table */
  1753. X        if (! EKMAPEEK(p->p_addr, mypgtbl)) {
  1754. X            (void) fprintf(stderr,
  1755. X                "%s: can't get mypgtbl.\n", progname);
  1756. X            return (struct user *)NULL;
  1757. X        }
  1758. X        /* now collect various pages of u area */
  1759. X        for (upage = 0, up = (page *)&User; upage < USERPAGES; upage++) {
  1760. X        if(! EMPPEEK(ctob(mypgtbl[upage].pg_pfnum), up)) {
  1761. X                (void) fprintf(stderr,
  1762. X                    "%s: can't get page %d of user area.\n",
  1763. X                    progname, upage);
  1764. X                return(NULL);
  1765. X            }
  1766. X            ++up;
  1767. X        }
  1768. X    }
  1769. X    return &User;
  1770. X}
  1771. X
  1772. X#endif /* ! DYNIX */
  1773. X#endif /* SunOS < 4 */
  1774. X
  1775. X
  1776. X/*
  1777. X * print mesg "s", don't exit if we are processing a core, 
  1778. X * so that corrupt entries don't prevent further uncorrupted
  1779. X * entries from showing up.
  1780. X */
  1781. error(s)
  1782. X    char *s;
  1783. X{
  1784. X    if (s && !k_opt)
  1785. X        (void) fprintf(stderr, "%s: %s", progname, s);
  1786. X    if (!k_opt)
  1787. X        exit(1);
  1788. X}
  1789. X
  1790. X/*
  1791. X * get some symbols form the kernel
  1792. X */
  1793. getsyms()
  1794. X{
  1795. X    register i;
  1796. X
  1797. X    if (k_opt) {
  1798. X#ifdef    ultrix
  1799. X        (void) nlist(namelist, nl);
  1800. X#else    /* not ultrix */
  1801. X        if (nlist(namelist, nl) == -1) {
  1802. X            (void) fprintf(stderr,
  1803. X                "%s: can't get name list from %s\n",
  1804. X                progname, namelist);
  1805. X            exit(1);
  1806. X        }
  1807. X#endif    /* ultrix */
  1808. X    } else {
  1809. X#ifdef    ultrix
  1810. X        (void) nlist("/vmunix", nl);
  1811. X#else    /* not ultrix */
  1812. X#ifdef    DYNIX
  1813. X        if (nlist("/dynix", nl) == -1)
  1814. X#else    /* not DYNIX */
  1815. X        if (nlist("/vmunix", nl) == -1)
  1816. X#endif    /* DYNIX */
  1817. X        {
  1818. X            (void) fprintf(stderr,
  1819. X                "%s: can't get name list from %s\n",
  1820. X#ifdef    DYNIX
  1821. X                progname, "/dynix");
  1822. X#else    /* not DYNIX */
  1823. X                progname, "/vmunix");
  1824. X#endif    /* DYNIX */
  1825. X            exit(1);
  1826. X        }
  1827. X#endif    /* ultrix */
  1828. X    }
  1829. X
  1830. X    for (i = 0; i < (sizeof(nl)/sizeof(nl[0]))-1; i++)
  1831. X        if (nl[i].n_value == 0) {
  1832. X            (void) fprintf(stderr, "%s: can't nlist symbol %s\n",
  1833. X                progname, nl[i].n_name);
  1834. X            exit(1);
  1835. X        }
  1836. X
  1837. X    KMPEEK(nl[X_PROC].n_value, procbase);
  1838. X    KMPEEK(nl[X_PROCNPROC].n_value, procNPROC);
  1839. X
  1840. X    return;
  1841. X}
  1842. X
  1843. X/*
  1844. X * When looking at kernel data space through /dev/mem or
  1845. X * with a core file, do virtual memory mapping.
  1846. X */
  1847. ls_t
  1848. vtophys(vaddr)
  1849. X#ifdef pyr
  1850. X    ;
  1851. X#else
  1852. X    ls_t vaddr;
  1853. X{
  1854. X    u_int paddr;
  1855. X    
  1856. X#ifdef    i386
  1857. X    if (vaddr < 8192)
  1858. X        return vaddr;
  1859. X#endif
  1860. X    paddr = nl[X_SYSMAP].n_value;
  1861. X    peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 1 page table", __LINE__);
  1862. X    paddr = (int)((int *)paddr + (vaddr / NBPG));
  1863. X    peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 2 page table", __LINE__);
  1864. X    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1865. X#ifndef    i386
  1866. X# define    PTBITS    0x1ff    /* 512 byte pages */
  1867. X#else
  1868. X# define    PTBITS    0xfff    /* 4096 byte pages */
  1869. X#endif
  1870. X
  1871. X    return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
  1872. X}
  1873. X#endif pyr    /* vtophys in a separate file for pyramid */
  1874. X
  1875. X/*
  1876. X * get file pointer for socket
  1877. X */
  1878. char *
  1879. getsockfp(cba, pfp)
  1880. X    char *cba;
  1881. X    struct file **pfp;
  1882. X{
  1883. X    register char *cp;
  1884. X    struct file *socktofile();
  1885. X    struct inpcb inpcb;
  1886. X    static char nmbuf[128];
  1887. X    struct socket sock;
  1888. X    struct tcpcb tcpcb;
  1889. X    long x;
  1890. X
  1891. X/*
  1892. X * Convert PCB address from ASCII to hex.
  1893. X */
  1894. X    for (cp = cba, x = 0l; *cp; cp++) {
  1895. X        x <<= 4;
  1896. X        if (*cp >= '0' && *cp <= '9')
  1897. X            x += *cp - '0';
  1898. X        else if (*cp >= 'a' && *cp <= 'f')
  1899. X            x += *cp - 'a' + 10;
  1900. X        else if (*cp >= 'A' && *cp <= 'F')
  1901. X            x += *cp - 'A' + 10;
  1902. X        else {
  1903. X            (void) fprintf(stderr,
  1904. X                "%s: non-hex address, %s\n", progname, cba);
  1905. X            return(NULL);
  1906. X        }
  1907. X    }
  1908. X/*
  1909. X * Read PCB and make sure it is in LISTEN or ESTABLISHED state.
  1910. X */
  1911. X    KMPEEK(x, tcpcb);
  1912. X    if (tcpcb.t_state < TCPS_LISTEN || tcpcb.t_state > TCPS_ESTABLISHED) {
  1913. X        (void) fprintf(stderr,
  1914. X            "%s: PCB %x not in LISTEN to ESTABLISHED state\n",
  1915. X            progname, x);
  1916. X        return(NULL);
  1917. X    }
  1918. X    if (tcpcb.t_inpcb == (struct inpcb *)0) {
  1919. X        (void) fprintf(stderr,
  1920. X            "%s: PCB %x has no INPCB\n",
  1921. X            progname, x);
  1922. X        return(NULL);
  1923. X    }
  1924. X/*
  1925. X * Read INPCB for PCB and make sure it points back to the PCB.
  1926. X */
  1927. X    KMPEEK(tcpcb.t_inpcb, inpcb);
  1928. X    if ((caddr_t)x != inpcb.inp_ppcb) {
  1929. X        (void) fprintf(stderr,
  1930. X            "%s: INPCB for PCB %x not linked to it\n",
  1931. X            progname, x);
  1932. X        return(NULL);
  1933. X    }
  1934. X/*
  1935. X * Read the socket and make sure it points back to the INPCB.
  1936. X */
  1937. X    KMPEEK(inpcb.inp_socket, sock);
  1938. X    if (sock.so_pcb != (caddr_t)tcpcb.t_inpcb) {
  1939. X        (void) fprintf(stderr,
  1940. X            "%s: socket not linked to INPCB for PCB %x\n",
  1941. X            progname, x);
  1942. X        return(NULL);
  1943. X    }
  1944. X/*
  1945. X * Find the file structure that is linked to the socket.
  1946. X */
  1947. X    if ((*pfp = socktofile((caddr_t)inpcb.inp_socket)) == NULL) {
  1948. X        (void) fprintf(stderr,
  1949. X            "%s: no file structure for socket of PCB %x\n",
  1950. X            progname, x);
  1951. X        return(NULL);
  1952. X    }
  1953. X/*
  1954. X * Construct a pseudo file name and return it.
  1955. X */
  1956. X    (void) sprintf(nmbuf,
  1957. X        "file %lx of socket %lx of INPCB %lx of PCB %lx",
  1958. X        (long)*pfp, (long)inpcb.inp_socket, (long)tcpcb.t_inpcb, x);
  1959. X    return(nmbuf);
  1960. X}
  1961. X
  1962. X/*
  1963. X * Convert a socket address to a file address.
  1964. X */
  1965. struct file *
  1966. socktofile(s)
  1967. X    caddr_t s;
  1968. X{
  1969. X    register struct file *afile;
  1970. X    char *calloc();
  1971. X    register struct file *fp;
  1972. X    static struct file *ftp;
  1973. X    static int nfile = -1;
  1974. X    static struct file *xfile = NULL;
  1975. X/*
  1976. X * Read the size of file table, allocate space
  1977. X * for it, and read the file table pointer (once).
  1978. X */
  1979. X    if (nfile < 0) {
  1980. X        KMPEEK(nl[SNFILE].n_value, nfile);
  1981. X        xfile = (struct file *) calloc((unsigned)nfile, sizeof (struct file));
  1982. X        KMPEEK(nl[SFIL].n_value, ftp);
  1983. X    }
  1984. X/*
  1985. X * Read the file table and search for an in-use
  1986. X * socket file with a matching data address.
  1987. X */
  1988. X    (void)peek(kmem, (ls_t)ftp, (char *)xfile, nfile * sizeof(struct file), "_file",
  1989. X            __LINE__, 0);
  1990. X    for (fp = xfile, afile = ftp; fp < &xfile[nfile]; fp++, afile++) {
  1991. X        if (fp->f_count && fp->f_type == DTYPE_SOCKET
  1992. X        &&  s == fp->f_data)
  1993. X            return(afile);
  1994. X    }
  1995. X    return(NULL);
  1996. X}
  1997. X
  1998. peek(file, fromwhere, intowhat, size, msg, line, errflg)
  1999. char *intowhat, *msg;
  2000. ls_t fromwhere;
  2001. X{
  2002. X    extern errno;
  2003. X    extern char *sys_errlist[];
  2004. X    int n;
  2005. X
  2006. X#if defined sun && SunOS >= 4
  2007. X    if (file == kmem) {
  2008. X        if ((n = kvm_read(kd,
  2009. X                 (unsigned long)(fromwhere), 
  2010. X                 (char *)(intowhat),
  2011. X                  size
  2012. X
  2013. X                )) == -1
  2014. X           ) goto bad;
  2015. X        return n;
  2016. X    }
  2017. X#endif
  2018. X    if (lseek(file, k_opt?vtophys(fromwhere):fromwhere, 0) == -1) goto bad;
  2019. X    if ((n = read(file, intowhat, size)) == -1) goto bad;
  2020. X    return n;
  2021. bad:
  2022. X    if (errflg > 0) return 0;
  2023. X    (void)fprintf (
  2024. X        stderr,
  2025. X        "%s: peek from 0x%x into 0x%x failed for %s at line %d (%s)\n",
  2026. X        progname,
  2027. X        fromwhere,
  2028. X        intowhat,
  2029. X        msg,
  2030. X        line,
  2031. X        sys_errlist[errno]
  2032. X    );
  2033. X    if (error == 0) exit(1);
  2034. X    return 0;
  2035. X}
  2036. X
  2037. X#if defined sun && SunOS >= 4 && SunOSrel >= 1
  2038. getuofiles(locu, segu)
  2039. register struct user *locu;
  2040. register struct seguser *segu;
  2041. X{
  2042. X    nofile = locu->u_lastfile + 1;
  2043. X    if (nofile <= 0) return;
  2044. X    ofilep = locu->u_ofile;
  2045. X    if (ofilep == segu->segu_u.u_ofile_arr)
  2046. X        ofilep = locu->u_ofile_arr;
  2047. X    else {
  2048. X        (void)peek(kmem, (ls_t)(ofilep), (char *)(ofile_arr), 
  2049. X             nofile*sizeof (struct file *), "ofile_arr", __LINE__, 0);
  2050. X        ofilep = ofile_arr;
  2051. X    }
  2052. X}
  2053. X#endif
  2054. END_OF_FILE
  2055. if test 34835 -ne `wc -c <'ofiles.c'`; then
  2056.     echo shar: \"'ofiles.c'\" unpacked with wrong size!
  2057. fi
  2058. # end of 'ofiles.c'
  2059. fi
  2060. echo shar: End of archive 1 \(of 1\).
  2061. cp /dev/null ark1isdone
  2062. MISSING=""
  2063. for I in 1 ; do
  2064.     if test ! -f ark${I}isdone ; then
  2065.     MISSING="${MISSING} ${I}"
  2066.     fi
  2067. done
  2068. if test "${MISSING}" = "" ; then
  2069.     echo You have the archive.
  2070.     rm -f ark[1-9]isdone
  2071. else
  2072.     echo You still need to unpack the following archives:
  2073.     echo "        " ${MISSING}
  2074. fi
  2075. ##  End of shell archive.
  2076. exit 0
  2077.